import request from '@/utils/request';
import { LOCALE_MAP } from '@/utils/utils';
import { getLocale } from 'umi';
import type { CacheD } from './cache';
import cache from './cache';
import { isJSONString } from './utils';

export interface CodeTypeItem {
  value: string;
  name: string;
  [prop: string]: any;
}

export type CodeList = CodeTypeItem[];

export type CodeValue = Record<string, any>;

const { codelist, codelistall } = cache;

// 异步获取
function getCodeListCache(type: string): Promise<CodeList>;
// 同步获取
function getCodeListCache(type: string, sync: boolean): CodeList;
// 设置值
function getCodeListCache(type: string, sync: boolean, value: any): void;
function getCodeListCache(type: string, sync = false, value?: CodeList) {
  // 存
  if (value) {
    if (sync) {
      codelist.set(`${type}:sync`, value);
    } else {
      codelist.set(type, value);
    }
  }
  // 取
  else if (sync) {
    return codelist.get(`${type}:sync`);
  } else {
    return codelist.get(type);
  }
}

const API = '/codeList/findByType';

function query(listType: string) {
  const task: Promise<CodeList> = request
    .post(API, {
      data: {
        value: listType,
      },
      serviceId: 'fwPlatform',
    })
    .then((list) => {
      // 缓存数据
      getCodeListCache(listType, true, list);
      return list;
    });
  // 缓存任务
  getCodeListCache(listType, false, task);
  return task;
}

/**
 * 异步获取编码列表
 * @param listType 编码类型
 * @param [cb] 获取list的回调，可以方便的与hooks函数结合
 */
export function getCodeList(listType: string, cb?: (list: CodeList) => any) {
  return (getCodeListCache(listType) || query(listType)).then((list: CodeList) => {
    if (cb) {
      cb(list);
    }
    return list;
  });
}

/**
 *  异步获取编码值
 * @param listType 编码类型
 * @param codeType 编码的值
 * @param [cb] 获取name的回调，可以方便的与hooks函数结合
 */
export function getCodeName(listType: string, codeType: string, cb?: (name: string) => any) {
  return getCodeList(listType).then((list: CodeList) => {
    for (const item of list) {
      if (item.value === codeType) {
        if (cb) {
          cb(item.name);
        }
        return item.name;
      }
    }
    return '';
    throw new Error(`在${listType}类型里面，没有找到${codeType}的编码`);
  });
}

/**
 * 根据列表查找编码
 * @param list codelist列表
 * @param codeType 需要查找name的code
 */
export function getCodeNameSync(list: CodeList, codeType: string) {
  for (const item of list) {
    if (item.value === codeType) {
      return item.name;
    }
  }
  return;
}

/**
 * 同步获取编码值
 * @param listType 类型
 * @param codeType 编码
 */
export function getCodeNameSyncSto(listType: string, codeType: string) {
  const list = getCodeListCache(listType, true);
  if (!list || !list.length) return '';
  for (const item of list) {
    if (item.value === codeType) {
      return item.name;
    }
  }
  return '';
}

/**
 * 同步获取编码列表
 * @param codeType 类型
 */
export function getCodeLocaleList(codeType: string) {
  const list = codelistall.get('default')[codeType] || [];
  return list.map((item: any) => ({
    ...item,
    name: isJSONString(item.name) ? JSON.parse(item.name)[LOCALE_MAP[getLocale()]] : item.name,
  }));
}

/**
 * 同步获取编码值的国际化显示文字
 * @param codeType 类型
 * @param value 编码的值
 */
export function getCodeLocaleName(codeType: string, value: string) {
  const codeTypeList = _.get(codelistall.get('default'), codeType);
  function getName(value: string): string {
    const code = _.find(codeTypeList, (item) => item.value === String(value));
    if (code) {
      if (isJSONString(code.name)) {
        const name = JSON.parse(code.name)[LOCALE_MAP[getLocale()]];
        return name;
      } else {
        return code.name;
      }
    }
    return value;
  }
  if (_.isArray(value)) {
    const text = _.reduce(value, (res, value) => res + ',' + getName(value), '');
    return text.slice(1, text.length);
  } else if (String(value).indexOf(',') >= 0) {
    const str = value.replace('[', '').replace(']', '');
    const valueArr = str.split(',');
    const text = _.reduce(valueArr, (res, value) => res + ',' + getName(value), '');
    return text.slice(1, text.length);
  } else {
    return getName(value);
  }
}

/**
 * 根据一个编码值同步获取当前编码对象的另一个字段的值
 * @param codeType 类型
 * @param fieldName 当前的字段名称
 * @param value 当前字段的值
 * @param anotherFieldName 另一字段的名称
 */
export function getCodeAnotherFieldValue(codeType: string, fieldName: string, value: string, anotherFieldName: string) {
  const list = codelistall.get('default')[codeType];
  if (Array.isArray(list)) {
    const code = list.find((item) => item[fieldName] === value);
    return code ? code[anotherFieldName] : '';
  } else {
    return '';
  }
}
